/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package analiseSintatica.Regras.DeclaracoesIniciais;

import analiseSintatica.Regras.Blocos.RegraDeclsInicial;
import AnaliseLexicaFinal.EstruturaDeDados.LinkToken;
import analiseSintatica.ErroSintaticoException;
import analiseSintatica.Regras.Expressoes.RegraExpressao;
import analiseSintatica.Regras.*;
import analiseSintatica.Regras.Tipos.RegraTipoPrimitivo;
import analiseSintatica.estruturadados.NoArvore;
import java.util.LinkedList;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Dede do Bem
 * 
 * <const> ::= const <tipo_primitivo> identificador "=" <expressao> ";"
 * 
 */
public class RegraConst extends Regra{

    protected static Regra instancia;

    protected String estrutura = "const <tipo_primitivo> identificador '=' <expressao> ';'";


    /**
     * Construtor privado necessario ao singleton
     */
    private RegraConst() {
    }

    /**
     * Retorna a unica instancia dessa classe.
     * @return
     */
    public static RegraConst getInstance() {
        if (instancia == null) {
            instancia = new RegraConst();
        }
        return (RegraConst) instancia;
    }

    @Override
    public NoArvore analisar(LinkedList<LinkToken> listaTokens) throws ErroSintaticoException {

        ErroSintaticoException erros = new ErroSintaticoException();
        
        NoArvore NaoTerminalConst = new NoArvore("<const>", false);
        
        NaoTerminalConst.adicionaFilho(reconheceConst(listaTokens)); //tirar o terminal const da lista de tokens e adicionar ele como um nófilho na sub arvore const

        try{
            NaoTerminalConst.adicionaFilho(RegraTipoPrimitivo.getInstance().analisar(listaTokens));
        }
        catch (ErroSintaticoException e) {
			while(e.size() != 0)
				erros.addErros(e.getErros());
	}

        try{
            NaoTerminalConst.adicionaFilho(reconheceToken(listaTokens, "identificador",estrutura));

        }catch(ErroSintaticoException e){
            
        }

        try{
            NaoTerminalConst.adicionaFilho(reconheceToken(listaTokens, "=",estrutura));

        }catch(ErroSintaticoException e){

        }

        try{
            NaoTerminalConst.adicionaFilho(RegraExpressao.getInstance().analisar(listaTokens));
        }
        catch (ErroSintaticoException e) {
			while(e.size() != 0)
				erros.addErros(e.getErros());
	}

        try{
            NaoTerminalConst.adicionaFilho(reconheceLexema(listaTokens, "delimitador", ";",estrutura));
        }catch(ErroSintaticoException e){
            
        }
        
        
        return NaoTerminalConst;
        
     }
   
       
    public NoArvore reconheceConst(LinkedList<LinkToken> listaTokens){
        listaTokens.removeFirst();
        return new NoArvore("const", true);
    }   
        
       

    @Override
    protected void setPrimeiro() {
        this.primeiro.add("const");
    }

    @Override
    protected void setSeguinte() {
        this.seguinte.add("void");
        //this.seguinte = RegraDeclsInicial.getInstance().getSeguinte();

    }

}
